[ORG 0x500]
[SECTION .text]
[BITS 16]
global _start_setup

_start_setup:
    mov ax,my_str
    call print

    ; 下面是进入保护模式代码
    ; 关中断
    cli
    ; 启用A20
    in al,0x92
    or al,2
    out 0x92,al

    ; 加载GDT
    lgdt [gdt_descriptor]
    
    ; 进入保护模式
    mov eax,cr0
    or eax,1
    mov cr0,eax

    jmp 0x08:protected_mode_entry

    jmp $

print:
    mov si,ax
    mov ah,0x0E
    .loop:
            mov al,[si]
            cmp al,0
            jz .done
            int 0x10

            inc si
            jmp .loop
       	.done:
            ret

gdt_start:
    dd 0
    dd 0
    ; 代码段
    dw 0xffff
    dw 0
    db 0
    db 0x9a
    db 0xcf
    db 0
    
    ; 数据段
    dw 0xffff
    dw 0
    db 0
    db 0x92
    db 0xcf
    db 0

    ; 显存段
    dw 0xfa0
    dw 0x8000
    db 0xb
    db 0x92
    db 0x40
    db 0
gdt_end:

gdt_descriptor:
    dw gdt_end-gdt_start-1
    dd gdt_start


my_str: db "this is setup",0

[BITS 32]
protected_mode_entry:
    mov ax,0x10
    mov ds,ax
    mov es,ax
    mov fs,ax
    mov gs,ax
    mov ss,ax

	mov esp,0x10000

	mov edi,0x10000
	mov ecx,2
	;mov bl,30
	mov bl, [0x7c00 + 0x1CA]
	call read_disk

    mov ax,protected_str
    call protected_print

	jmp 0x10000

    
    hlt

; ax为字符地址
protected_print:
    mov si,ax
    mov ax,0
    mov di,ax
    push es
    mov ax,0x18
    mov es,ax
    .loop:
        mov al,[si]
        cmp al,0
        jz .done
        mov byte [es:di],al
        inc si
        inc di
        inc di
        jmp .loop
    .done:
        pop es
        ret



read_disk:
    mov dx,0x1f2
    mov al,bl
    out dx,al

    inc dx ; 0x1f3
    mov al,cl
    out dx,al

    inc dx ; 0x1f4
	shr ecx,8
    mov al,cl
    out dx,al
    
    inc dx ; 0x1f5
	shr ecx,8
	mov al,cl
    out dx,al

    inc dx ; 0x1f6
	shr ecx,8
	and cl,0b1111

    mov al,0b1110_0000
	or al,cl
    out dx,al

    inc dx ; 0x1f7
    mov al,0x20
    out dx,al

	xor ecx,ecx
    mov cl,bl

    .read:
        push cx
        call .waits
        call .reads
        pop cx
        loop .read
	ret
		.waits:
			mov dx,0x1f7
			.check:
				in al,dx
				jmp $+2
				jmp $+2
				jmp $+2
				and al,0b1000_1000
				cmp al,0b0000_1000
				jnz .check
			ret
		.reads:
			mov dx,0x1f0
			mov cx,256
			.readw:
				in ax,dx
				jmp $+2
				jmp $+2
				jmp $+2
				mov [edi],ax
				add edi,2
				loop .readw
			ret
				
protected_str:
    db "this is protected",0


times 512-($-$$) db 0
